home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / Miro_Downloader.exe / singleclick.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2007-11-12  |  12.7 KB  |  366 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. """Helper functions for implement single click playback and single click
  5. torrent downloading.
  6.  
  7. Frontends should call setCommandLineArgs() passing it a list of arguments that
  8. the users gives.  This should just be suspected torrents/videos, not things
  9. like '--help', '--version', etc.
  10.  
  11. Frontends should trap when a user opens a torrent/video with democracy while
  12. democracy is already running.  They should arange for addVideo or addTorrent
  13. to be called in the existing democracy process.
  14. """
  15. from gtcache import gettext as _
  16. import os
  17. import logging
  18. import urllib
  19. from util import getTorrentInfoHash
  20. import app
  21. import dialogs
  22. import download_utils
  23. import item
  24. import feed
  25. import filetypes
  26. import folder
  27. import httpclient
  28. import views
  29. import platformutils
  30. import subscription
  31. import util
  32. import config
  33. import prefs
  34. from string import Template
  35. _commandLineArgs = []
  36. commandLineVideoIds = None
  37. commandLineView = None
  38.  
  39. def getManualFeed():
  40.     manualFeed = util.getSingletonDDBObject(views.manualFeed)
  41.     manualFeed.confirmDBThread()
  42.     return manualFeed
  43.  
  44.  
  45. def addVideo(path, single = False):
  46.     path = os.path.abspath(path)
  47.     views.items.confirmDBThread()
  48.     for i in views.items:
  49.         itemFilename = i.getFilename()
  50.         if itemFilename != '' and os.path.exists(itemFilename) and platformutils.samefile(itemFilename, path):
  51.             print 'Not adding duplicate video: %s' % path.decode('ascii', 'ignore')
  52.             commandLineVideoIds.add(i.getID())
  53.             return None
  54.             continue
  55.     
  56.     fileItem = item.FileItem(path, feed_id = correctFeed.getID())
  57.     fileItem.markItemSeen()
  58.     commandLineVideoIds.add(fileItem.getID())
  59.  
  60.  
  61. def checkURLExists(url):
  62.     manualFeed = getManualFeed()
  63.     for i in manualFeed.items:
  64.         if i.getURL() == url:
  65.             title = _('Download already exists')
  66.             text1 = _('That URL is already an external download.')
  67.             downloadState = None
  68.             if i.downloader is not None:
  69.                 downloadState = i.downloader.getState()
  70.             
  71.             if downloadState in ('paused', 'stopped'):
  72.                 i.download()
  73.                 text2 = _('Miro will begin downloading it now.')
  74.             elif downloadState == 'downloading':
  75.                 text2 = _('It is downloading now.')
  76.             else:
  77.                 text2 = _('It has already been downloaded.')
  78.             dialogs.MessageBoxDialog(title, '%s  %s' % (text1, text2)).run()
  79.             return True
  80.             continue
  81.     
  82.     existingFeed = feed.getFeedByURL(url)
  83.     if existingFeed is not None:
  84.         existingFeed.blink()
  85.         return True
  86.     
  87.     return False
  88.  
  89.  
  90. def addDownload(url):
  91.     if checkURLExists(url):
  92.         return None
  93.     
  94.     
  95.     def callback(headers):
  96.         if checkURLExists(url):
  97.             return None
  98.         
  99.         contentType = headers.get('content-type')
  100.         if filetypes.isFeedContentType(contentType):
  101.             addFeeds([
  102.                 url])
  103.         else:
  104.             entry = item.getEntryForURL(url, contentType)
  105.             if filetypes.isVideoEnclosure(entry['enclosures'][0]):
  106.                 downloadVideo(entry)
  107.             else:
  108.                 downloadUnknownMimeType(url)
  109.  
  110.     
  111.     def errback(error):
  112.         title = _('Download Error')
  113.         text = _('Miro is not able to download a file at this URL:\n\nURL: %s') % url
  114.         dialogs.MessageBoxDialog(title, text).run()
  115.  
  116.     httpclient.grabHeaders(url, callback, errback)
  117.  
  118.  
  119. def downloadUnknownMimeType(url):
  120.     title = _('File Download')
  121.     text = _('This file at %s does not appear to be audio, video, or an RSS feed.') % url
  122.     dialog = dialogs.ChoiceDialog(title, text, dialogs.BUTTON_DOWNLOAD_ANYWAY, dialogs.BUTTON_CANCEL)
  123.     
  124.     def callback(dialog):
  125.         if checkURLExists(url):
  126.             return None
  127.         
  128.         if dialog.choice == dialogs.BUTTON_DOWNLOAD_ANYWAY:
  129.             downloadVideo(item.getEntryForURL(url, 'video/x-unknown'))
  130.         
  131.  
  132.     dialog.run(callback)
  133.  
  134.  
  135. def downloadVideo(entry):
  136.     manualFeed = getManualFeed()
  137.     newItem = item.Item(entry, feed_id = manualFeed.getID())
  138.     newItem.download()
  139.     app.controller.selection.selectTabByTemplateBase('downloadtab')
  140.  
  141.  
  142. def addTorrent(path, torrentInfohash):
  143.     manualFeed = getManualFeed()
  144.     for i in manualFeed.items:
  145.         if i.downloader is not None and i.downloader.status.get('infohash') == torrentInfohash:
  146.             print "Not downloading %s, it's already a download for %s" % (path, i)
  147.             if i.downloader.getState() in ('paused', 'stopped'):
  148.                 i.download()
  149.             
  150.             return None
  151.             continue
  152.     
  153.     newItem = item.Item(item.getEntryForFile(path), feed_id = manualFeed.getID())
  154.     newItem.download()
  155.  
  156.  
  157. def resetCommandLineView():
  158.     global commandLineView, commandLineVideoIds
  159.     if commandLineView is not None:
  160.         commandLineView.unlink()
  161.         commandLineView = None
  162.     
  163.     commandLineVideoIds = set()
  164.  
  165.  
  166. def inCommandLineVideoIDs(item):
  167.     return item.getID() in commandLineVideoIds
  168.  
  169.  
  170. def playCommandLineView():
  171.     global commandLineView
  172.     if len(commandLineVideoIds) == 0:
  173.         return None
  174.     
  175.     commandLineView = views.items.filter(inCommandLineVideoIDs)
  176.     firstItemId = commandLineVideoIds.__iter__().next()
  177.     app.controller.playbackController.configure(commandLineView, firstItemId)
  178.     app.controller.playbackController.enterPlayback()
  179.  
  180.  
  181. def addFeed(path):
  182.     feed.addFeedFromFile(path)
  183.  
  184.  
  185. def addSubscriptions(path):
  186.     urls = subscription.parseFile(path)
  187.     if urls is not None:
  188.         if len(urls) > 1:
  189.             askForMultipleFeeds(urls)
  190.         else:
  191.             addFeeds(urls)
  192.     
  193.  
  194.  
  195. def filterExistingFeedURLs(urls):
  196.     return _[1]
  197.  
  198.  
  199. def addFeeds(urls, newFolderName = None):
  200.     if len(urls) > 0:
  201.         lastFeed = None
  202.         if newFolderName is not None:
  203.             newFolder = folder.ChannelFolder(newFolderName)
  204.         
  205.         for url in filterExistingFeedURLs(urls):
  206.             f = feed.Feed(url)
  207.             if newFolderName is not None:
  208.                 f.setFolder(newFolder)
  209.             
  210.             lastFeed = f
  211.         
  212.         if newFolderName is None:
  213.             if lastFeed:
  214.                 for url in urls:
  215.                     f = feed.getFeedByURL(url)
  216.                     if f is lastFeed:
  217.                         app.controller.selection.selectTabByObject(f)
  218.                         continue
  219.                     f.blink()
  220.                 
  221.             else:
  222.                 for i in xrange(len(urls) - 1):
  223.                     feed.getFeedByURL(urls[i]).blink()
  224.                 
  225.                 f = feed.getFeedByURL(urls[-1])
  226.                 app.controller.selection.selectTabByObject(f)
  227.         else:
  228.             app.controller.selection.selectTabByObject(newFolder)
  229.     
  230.  
  231.  
  232. def askForMultipleFeeds(urls):
  233.     title = _('Subscribing to multiple channels')
  234.     description = _('Create %d channels?') % len(urls)
  235.     d = dialogs.ThreeChoiceDialog(title, description, dialogs.BUTTON_ADD, dialogs.BUTTON_ADD_INTO_NEW_FOLDER, dialogs.BUTTON_CANCEL)
  236.     
  237.     def callback(d):
  238.         if d.choice == dialogs.BUTTON_ADD:
  239.             addFeeds(urls)
  240.         elif d.choice == dialogs.BUTTON_ADD_INTO_NEW_FOLDER:
  241.             askForNewFolderName(urls)
  242.         
  243.  
  244.     d.run(callback)
  245.  
  246.  
  247. def askForNewFolderName(urls):
  248.     newURLCount = len(filterExistingFeedURLs(urls))
  249.     existingURLCount = len(urls) - newURLCount
  250.     title = _('Adding %d channels to a new folder') % newURLCount
  251.     description = _('Enter a name for the new channel folder')
  252.     if existingURLCount > 0:
  253.         description += '\n\n'
  254.         description += _('NOTE: You are already subscribed to %d of these channels.  These channels will stay where they currently are.' % existingURLCount)
  255.     
  256.     
  257.     def callback(d):
  258.         if d.choice == dialogs.BUTTON_CREATE:
  259.             addFeeds(urls, d.value)
  260.         
  261.  
  262.     dialogs.TextEntryDialog(title, description, dialogs.BUTTON_CREATE, dialogs.BUTTON_CANCEL).run(callback)
  263.  
  264.  
  265. def complainAboutSubscriptionURL(messageText):
  266.     title = _('Subscription error')
  267.     dialogs.MessageBoxDialog(title, messageText).run()
  268.  
  269.  
  270. def addSubscriptionURL(prefix, expectedContentType, url):
  271.     realURL = url[len(prefix):]
  272.     
  273.     def callback(info):
  274.         if info.get('content-type') == expectedContentType:
  275.             urls = subscription.parseContent(info['body'])
  276.             if urls is None:
  277.                 complainAboutSubscriptionURL(Template(_('This $shortAppName channel file has an invalid format: $url. Please notify the publisher of this file.')).substitute(url = realURL, shortAppName = config.get(prefs.SHORT_APP_NAME)))
  278.             elif len(urls) > 1:
  279.                 askForMultipleFeeds(urls)
  280.             else:
  281.                 addFeeds(urls)
  282.         else:
  283.             complainAboutSubscriptionURL(Template(_('This $shortAppName channel file has the wrong content type: $url. Please notify the publisher of this file.')).substitute(url = realURL, shortAppName = config.get(prefs.SHORT_APP_NAME)))
  284.  
  285.     
  286.     def errback(error):
  287.         complainAboutSubscriptionURL(Template(_('Could not download the $shortAppName channel file: $url.')).substitute(url = realURL, shortAppName = config.get(prefs.SHORT_APP_NAME)))
  288.  
  289.     httpclient.grabURL(realURL, callback, errback)
  290.  
  291.  
  292. def handleCommandLineArgs(args):
  293.     if app.controller.finishedStartup:
  294.         parseCommandLineArgs(args)
  295.     else:
  296.         setCommandLineArgs(args)
  297.  
  298.  
  299. def setCommandLineArgs(args):
  300.     _commandLineArgs.extend(args)
  301.  
  302.  
  303. def parseCommandLineArgs(args = None):
  304.     global _commandLineArgs
  305.     if args is None:
  306.         args = _commandLineArgs
  307.         _commandLineArgs = []
  308.     
  309.     resetCommandLineView()
  310.     addedVideos = False
  311.     addedDownloads = False
  312.     for arg in args:
  313.         if arg.startswith('file://'):
  314.             arg = download_utils.getFileURLPath(arg)
  315.         
  316.         if arg.startswith('miro:'):
  317.             addSubscriptionURL('miro:', 'application/x-miro', arg)
  318.             continue
  319.         if arg.startswith('democracy:'):
  320.             addSubscriptionURL('democracy:', 'application/x-democracy', arg)
  321.             continue
  322.         if arg.startswith('http:') or arg.startswith('https:'):
  323.             addDownload(platformutils.filenameToUnicode(arg))
  324.             continue
  325.         if os.path.exists(arg):
  326.             ext = os.path.splitext(arg)[1].lower()
  327.             if ext in ('.torrent', '.tor'):
  328.                 
  329.                 try:
  330.                     torrentInfohash = getTorrentInfoHash(arg)
  331.                 except ValueError:
  332.                     title = _('Invalid Torrent')
  333.                     msg = _('The torrent file %s appears to be corrupt and cannot be opened. [OK]') % os.path.basename(arg)
  334.                     dialogs.MessageBoxDialog(title, msg).run()
  335.                     continue
  336.  
  337.                 addTorrent(arg, torrentInfohash)
  338.                 addedDownloads = True
  339.             elif ext in ('.rss', '.rdf', '.atom', '.ato'):
  340.                 addFeed(arg)
  341.             elif ext in ('.miro', '.democracy', '.dem', '.opml'):
  342.                 addSubscriptions(arg)
  343.             else:
  344.                 addVideo(arg, len(args) == 1)
  345.                 addedVideos = True
  346.         ext in ('.torrent', '.tor')
  347.         print "WARNING: %s doesn't exist" % arg
  348.     
  349.     if addedVideos:
  350.         app.controller.selection.selectTabByTemplateBase('librarytab', False)
  351.         playCommandLineView()
  352.     elif addedDownloads:
  353.         app.controller.selection.selectTabByTemplateBase('downloadtab')
  354.     
  355.  
  356.  
  357. def openFile(path):
  358.     parseCommandLineArgs([
  359.         path])
  360.  
  361.  
  362. def downloadURL(url):
  363.     parseCommandLineArgs([
  364.         url])
  365.  
  366.